package com.shelpe.services.simbasync.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.shelpe.services.simbasync.dao.CreativesMapper;
import com.shelpe.services.simbasync.dao.RptAdgroupCreativeMapper;
import com.shelpe.services.simbasync.exception.ApiException;
import com.shelpe.services.simbasync.model.Creatives;
import com.shelpe.services.simbasync.model.CreativesExample;
import com.shelpe.services.simbasync.model.RptAdgroupCreative;
import com.shelpe.services.simbasync.model.RptAdgroupCreativeExample;
import com.shelpe.services.simbasync.service.CreativesService;
import com.shelpe.services.simbasync.util.Util;

@Service
public class CreativesServiceImpl implements CreativesService {
	
	private static final Logger logger = LoggerFactory.getLogger(CreativesServiceImpl.class);
	
	@Autowired
	private CreativesMapper mapper;
	
	@Autowired
	private RptAdgroupCreativeMapper rptmapper;
	
	@Override
	public int addCreative(Creatives creative) {//过滤掉重复的
		// TODO Auto-generated method stub
		return mapper.insert(creative);
	}

	@Override
	public int addCreativeList(List<Creatives> creatives) {
		// TODO Auto-generated method stub
		int num = 0;
		for(Creatives item : creatives){
			num += mapper.insert(item);
		}
		return num;
	}

	@Override
	public int addRptCreatives(RptAdgroupCreative rpt) {
		// TODO Auto-generated method stub
		return rptmapper.insert(rpt);
	}

	@Override
	public int deleteRptCreativesByDateRange(List<Long> adgroupIds, Date startDate, Date endDate){
		
		RptAdgroupCreativeExample example = new RptAdgroupCreativeExample();
		example.createCriteria()
		.andDateBetween(startDate, endDate)
		.andAdgroupIdIn(adgroupIds);
		
		return rptmapper.deleteByExample(example);
	}
	
	@Override
	public int addRptCreativesList(List<RptAdgroupCreative> rptList) {
		// TODO Auto-generated method stub
		int num = 0;
		for(RptAdgroupCreative rpt : rptList){
			num += rptmapper.insert(rpt);
		}
		return num;
	}
	
	@Override
	public int insertRptCreativeBatch(List<RptAdgroupCreative> rptList){
		int num = 0;
		int pageSize = 15000;
		
		if(rptList != null && rptList.size() > 0){
			int fromIndex = 0;
			int endIndex = 0;
			do{
				
				endIndex += pageSize; 
				if(endIndex > rptList.size()){
					endIndex = rptList.size();
				}
				num += rptmapper.insertBatch(rptList.subList(fromIndex, endIndex));	
				fromIndex += pageSize; 
			
			}while(fromIndex < rptList.size());
		}
		
		return num;
	}

	@Override
	public int deleteCreative(Creatives ad) {
		// TODO Auto-generated method stub
		return mapper.deleteByPrimaryKey(ad.getCreativeId());
	}

	@Override
	public int deleteCreativeList(List<Creatives> adList) {
		// TODO Auto-generated method stub
		int num = 0;
		for(Creatives cr : adList){
			num += deleteCreative(cr);
		}
		return num;
	}

	@Override
	public int updateCreative(Creatives ad) {
		// TODO Auto-generated method stub
		return mapper.updateByPrimaryKey(ad);
	}

	@Override
	public int updateCreativeList(List<Creatives> adList) {
		// TODO Auto-generated method stub
		int num = 0;
		for(Creatives cr : adList){
			num += mapper.updateByPrimaryKey(cr);
		}
		return num;
	}

	@Override
	public List<Creatives> getCreativeList(List<Long> creativeIds, Long adGroupId) {
		// TODO Auto-generated method stub
		List<Creatives> list;
		CreativesExample ex = new CreativesExample();
		if(adGroupId != null){
			ex.createCriteria().andAdgroupIdEqualTo(adGroupId);
			list = mapper.selectByExample(ex);
		}else{
			ex.createCriteria().andCreativeIdIn(creativeIds);
			list = mapper.selectByExample(ex);
		}
		return list;
	}

	@Override
	public List<Creatives> parseJsonToCreatives(String response) {
		// TODO Auto-generated method stub

		List<Creatives> list = new ArrayList<Creatives>();
		
		if(response != null && response.contains("simba_creatives_get_response")){
			JSONObject object = JSON.parseObject(response);
			JSONObject objRes = object==null? null : object.getJSONObject("simba_creatives_get_response");
			JSONObject objItems = objRes==null? null : objRes.getJSONObject("creatives");
			JSONArray jsonList = objItems==null? null : objItems.getJSONArray("creative");
			int size = jsonList == null? 0 : jsonList.size();
		
			for(int i = 0; i < size; i++){
				JSONObject item = jsonList.getJSONObject(i);
				//解析
				Creatives ad = new Creatives();
				ad.setAdgroupId(item.getLong("adgroup_id"));
				ad.setCampaignId(item.getLong("campaign_id"));
				ad.setCreateTime(item.getDate("create_time"));
				ad.setModifiedTime(item.getDate("modified_time"));
				ad.setNick(item.getString("nick"));
				String auditDesc = item.getString("audit_desc");
				auditDesc = auditDesc == null ? "" : auditDesc;
				ad.setAuditDesc(auditDesc);
				ad.setAuditStatus(item.getString("audit_status"));
				ad.setCreativeId(item.getLong("creative_id"));
				ad.setImgUrl(item.getString("img_url"));
				ad.setTitle(item.getString("title"));
				
				list.add(ad);
			}	
		}else{
			logger.warn("can not get any info from proxy, maybe something is wrong, api is parseJsonToCreatives, response: {}", response);
			throw new ApiException();
		}
		
		return list;
	}

	@Override
	public void updateCreativesData(long userId, List<Creatives> list){
		
		Date updatedTime =  new Date();
		
		for(Creatives item : list){
			item.setUserId(userId);
			item.setUpdatedTime(updatedTime);
		}
	}

	@Override
	public Map<String, List<Creatives>> splitCreatives(List<Creatives> newList, List<Creatives> oldList) {
		// TODO Auto-generated method stub
		Map<String, List<Creatives> > ret = new HashMap<String, List<Creatives> >();
		List<Creatives> updated = new ArrayList<Creatives>();
		List<Creatives> deleted = new ArrayList<Creatives>();
		List<Creatives> added = new ArrayList<Creatives>();
		Set<Long> newAdIds = new HashSet<Long>();
		int oldSize = oldList == null? 0 : oldList.size();
		int i = 0;
		
		for(Creatives newItem : newList){
			
			for(i = 0; i < oldSize; i++){
				Creatives oldItem = oldList.get(i);
				if(newItem.getCreativeId().equals(oldItem.getCreativeId())){
					//比较其他字段是否相同
					if(!isEqualCreatives(newItem, oldItem)){
						updated.add(newItem);
					}
					break;
				}
			}
			if(i == oldSize){
				added.add(newItem);
			}
			newAdIds.add(newItem.getCreativeId());
		}
		
		for(Creatives oldItem : oldList){
			if(!newAdIds.contains(oldItem.getCreativeId())){
				deleted.add(oldItem);
			}
		}
		ret.put("delete", deleted);	
		ret.put("update", updated);	
		ret.put("add", added);	
				
		return ret;
	}
	
	private boolean isEqualCreatives(Creatives newAd, Creatives oldAd){
		
		if(newAd.getAuditDesc().equals(oldAd.getAuditDesc()) &&
				newAd.getModifiedTime().getTime() == oldAd.getModifiedTime().getTime() &&
				newAd.getAuditStatus().equals(oldAd.getAuditStatus())){
			return true;
		}
		
		return false;
	}

	@Override
	public Date getLastTimeFromRpt(long userId, long campaignId, long adgroupId) {
		// TODO Auto-generated method stub
		return rptmapper.getLastTimeFromRpt(userId, campaignId, adgroupId);
	}

	@Override
	public List<RptAdgroupCreative> parseJsonToRptAdgroupCreativeBase(String response) {
		// TODO Auto-generated method stub
		List<RptAdgroupCreative> ret = new ArrayList<RptAdgroupCreative>();
		
		if(response != null && response.contains("simba_rpt_adgroupcreativebase_get_response")){
			JSONObject object = JSON.parseObject(response);
			JSONObject objRes = object==null? null : object.getJSONObject("simba_rpt_adgroupcreativebase_get_response");
			JSONArray jsonList = objRes==null? null : objRes.getJSONArray("rpt_adgroupcreative_base_list");
			int size = jsonList == null? 0 : jsonList.size();
			
			for(int i = 0; i < size; i++){
				JSONObject item = jsonList.getJSONObject(i);
				RptAdgroupCreative rpt = new RptAdgroupCreative();
				
				int impression = NumberUtils.toInt(item.getString("impressions"), 0);
				int cost = NumberUtils.toInt(item.getString("cost"), 0);
				int click = NumberUtils.toInt(item.getString("click"), 0);
				float ctr = NumberUtils.toFloat(item.getString("ctr"), 0.0f);
				float cpc = NumberUtils.toFloat(item.getString("cpc"), 0.0f);
				float cpm = NumberUtils.toFloat(item.getString("cpm"), 0.0f);
				float avgpos = NumberUtils.toFloat(item.getString("avgpos"), 0.0f);
				
				rpt.setCpc(cpc);
				rpt.setCtr(ctr) ;
				rpt.setImpressions(impression) ;
				rpt.setCpm(cpm);
				rpt.setClick(click);
				rpt.setCost(cost) ;
				rpt.setCampaignId(item.getLong("campaignId"));
				rpt.setDate(item.getDate("date"));
				rpt.setSearchType(item.getByte("searchtype"));
				rpt.setSource(item.getByte("source"));
				rpt.setAvgpos(avgpos);
				rpt.setCreativeId(item.getLong("creativeId"));
				rpt.setAdgroupId(item.getLong("adgroupId"));
			
				rpt.setDirectPay(0);
				rpt.setIndirectPay(0); 
				rpt.setDirectPayCount(0);
				rpt.setIndirectPayCount(0);
				rpt.setFavShopCount(0);
				rpt.setFavItemCount(0); 	
				
				ret.add(rpt);
			}
		}else{
			logger.warn("can not get any info from proxy, maybe something is wrong, api is parseJsonToRptAdgroupCreativeBase, response: {}", response);
			throw new ApiException();
		}
		
		return ret;
	}

	@Override
	public int combineRptAdgroupCreativeEffect(String response, Map<String, Integer> lastDayRecord, List<RptAdgroupCreative> list) {
		// TODO Auto-generated method stub
		int size = 0;
		int lastDayRecordTotal = 0;
		int lastDayNoDataNum = 0;
		if(response != null && response.contains("simba_rpt_adgroupcreativeeffect_get_response")){
			JSONObject object = JSON.parseObject(response);
			JSONObject objRes = object==null? null : object.getJSONObject("simba_rpt_adgroupcreativeeffect_get_response");
			JSONArray jsonList = objRes==null? null : objRes.getJSONArray("rpt_adgroupcreative_effect_list");
			size = jsonList == null? 0 : jsonList.size();
			Date lastDay = Util.getLastDayYYYYMMDD();
			
			for(int i = 0; i < size; i++){
				JSONObject item = jsonList.getJSONObject(i);
				
				if(item.getDate("date").getTime() == lastDay.getTime()){//前一天的数据会出现这种情况
					lastDayRecordTotal++;
					if(!(item.containsKey("indirectpay") || item.containsKey("favItemCount") || item.containsKey("indirectpaycount") ||
							item.containsKey("favShopCount") || item.containsKey("directpay") || item.containsKey("directpaycount"))){
						//这些都没有，认为没有数据，
						lastDayNoDataNum++;
						continue;
					}
				}
				
				int indirectpay = NumberUtils.toInt(item.getString("indirectpay"), 0);
				int	favItemCount = NumberUtils.toInt(item.getString("favItemCount"), 0);
				int	indirectpaycount = NumberUtils.toInt(item.getString("indirectpaycount"), 0);
				int	favShopCount = NumberUtils.toInt(item.getString("favShopCount"), 0);
				int	directpay = NumberUtils.toInt(item.getString("directpay"), 0);
				int	directpaycount = NumberUtils.toInt(item.getString("directpaycount"), 0);
				
				//根据key找到相关的
				for(RptAdgroupCreative rpt : list){
					if(rpt.getCampaignId().equals(item.getLong("campaignId")) &&
							rpt.getAdgroupId().equals(item.getLong("adgroupId")) &&
							rpt.getCreativeId().equals(item.getLong("creativeId")) &&
							rpt.getSource().equals(item.getByte("source")) &&
							rpt.getSearchType().equals(item.getByte("searchtype")) && 
							rpt.getDate().getTime() == item.getDate("date").getTime()){

						rpt.setDirectPay(directpay) ;
						rpt.setIndirectPay(indirectpay); 
						rpt.setDirectPayCount(directpaycount);
						rpt.setIndirectPayCount(indirectpaycount);
						rpt.setFavShopCount(favShopCount) ;
						rpt.setFavItemCount(favItemCount); 	
						
						break;
					}
				}		
			}
		}else{
			logger.warn("can not get any info from proxy, maybe something is wrong, api is combineRptAdgroupCreativeEffect, response: {}", response);
			throw new ApiException();
		}
		lastDayRecord.put("total", lastDayRecordTotal);
		lastDayRecord.put("lost", lastDayNoDataNum);
		
		return size;
	}

	@Override
	public void updateRptAdgroupCreativeData(long userId, List<RptAdgroupCreative> list) {
		// TODO Auto-generated method stub
		
		for(RptAdgroupCreative rpt : list){
			rpt.setTaobaoUserId(userId);
		}
	}

	

}